package com.atguigu.tingshu.order.strategy.impl;
import java.math.BigDecimal;

import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.google.common.collect.Lists;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import com.google.common.collect.Maps;

import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.strategy.SaveOrderStrategy;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service        // 微信支付保存订单策略方法
public class WeiXinSaveOrderStrategy implements SaveOrderStrategy {

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderDerateMapper orderDerateMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public OrderInfoVo saveOrder(OrderInfoVo orderInfoVo) {
        log.info("WeiXinSaveOrderStrategy...方法执行了...");

        // 保存订单基本数据以及明细数据和减免明细数据
        this.saveOrderInfoAndDetailAndDerateInfo(orderInfoVo);

        // 向Redis中发布延迟任务
        this.sendDelayTask(orderInfoVo);



        return orderInfoVo;
    }

    private void sendDelayTask(OrderInfoVo orderInfoVo) {
        // 向Redis中发布延迟任务
        RBlockingDeque<String> blockingDeque = redissonClient.getBlockingDeque("order:info:delay:queue");
        RDelayedQueue<String> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
        delayedQueue.offer(orderInfoVo.getTradeNo() , RedisConstant.ORDER_INFO_TIME_OUT , TimeUnit.SECONDS);
    }

    private void saveOrderInfoAndDetailAndDerateInfo(OrderInfoVo orderInfoVo) {

        //获取用户数据
        Long userId = AuthContextHolder.getUserId();

        //保存订单的数据 1.保存订单的基本数据 2.保存订单的明细数据 3.保存订单的减免明细数据


        //1.保存订单的基本数据
        // 从明细列表中获取第一条明细数据，从该明细数据中获取明细名称，将其作为订单标题
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        OrderDetailVo orderDetailVo = orderDetailVoList.get(0);
        OrderInfo orderInfo = new OrderInfo();    //保存订单的基本数据
        orderInfo.setUserId(userId);
        orderInfo.setOrderTitle(orderDetailVo.getItemName());
        orderInfo.setOrderNo(orderInfoVo.getTradeNo());
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_UNPAID);
        orderInfo.setOriginalAmount(orderInfoVo.getOriginalAmount());
        orderInfo.setDerateAmount(orderInfoVo.getDerateAmount());
        orderInfo.setOrderAmount(orderInfoVo.getOrderAmount());
        orderInfo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);

        // 保存订单数据
        orderInfoMapper.insert(orderInfo);

        //2.保存订单的明细数据
        // 保存订单明细数据
        orderDetailVoList.forEach(odv -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderInfo.getId());             // 订单的id
            BeanUtils.copyProperties(odv, orderDetail);
            orderDetailMapper.insert(orderDetail);
        });

        // 保存订单减免明细数据
        List<OrderDerateVo> orderDerateVoList = orderInfoVo.getOrderDerateVoList();
        if (!CollectionUtils.isEmpty(orderDerateVoList)) {
            orderDerateVoList.forEach(orderDerateVo -> {
                OrderDerate orderDerate = new OrderDerate();
                orderDerate.setOrderId(orderInfo.getId());
                BeanUtils.copyProperties(orderDerateVo, orderDerate);
                orderDerateMapper.insert(orderDerate);
            });

        }
    }

    @Override
    public String getPayWay() {
        return SystemConstant.ORDER_PAY_WAY_WEIXIN;  // 微信支付
    }

    @Override
    public void saveOrderAfterProcess(OrderInfoVo orderInfoVo) {
        this.sendDelayTask(orderInfoVo);   // // 向Redis中发布延迟任务 保存订单数据以后的后续操作
    }
}